package com.apkicon.core;

import com.apkicon.model.IconInfo;
import com.apkicon.parser.OptimizedAdaptiveIconXmlParser;
import com.apkicon.parser.OptimizedApkResourceResolver;
import com.apkicon.parser.ApkParserLibrary;
import com.apkicon.parser.StandardAdaptiveIconParser;
import com.apkicon.processor.OptimizedAdaptiveIconProcessor;
import com.apkicon.processor.NativeStyleAdaptiveIconProcessor;
import com.apkicon.processor.PngIconProcessor;
import com.apkicon.processor.IconProcessor;
import net.dongliu.apk.parser.ApkFile;
import javax.imageio.ImageIO;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * 增强的APK图标提取器
 * 提供完善的错误处理、异常恢复和性能监控
 */
public class EnhancedApkIconExtractor {
    
    // 配置参数
    private static final int DEFAULT_TIMEOUT_SECONDS = 30;
    private static final int MAX_RETRY_ATTEMPTS = 3;
    
    // 性能监控
    private static long totalProcessingTime = 0;
    private static int totalProcessedCount = 0;
    private static int successCount = 0;
    private static int failureCount = 0;
    
    /**
     * 提取APK图标 - 增强版本
     */
    public static IconInfo extractIcon(File apkFile, int targetSize) throws Exception {
        return extractIcon(apkFile, targetSize, DEFAULT_TIMEOUT_SECONDS);
    }
    
    /**
     * 提取APK图标 - 带超时控制
     */
    public static IconInfo extractIcon(File apkFile, int targetSize, int timeoutSeconds) throws Exception {
        return extractIcon(apkFile, targetSize, timeoutSeconds, true); // 默认使用原生风格
    }
    
    /**
     * 提取APK图标 - 带超时控制和风格选择
     */
    public static IconInfo extractIcon(File apkFile, int targetSize, int timeoutSeconds, boolean useNativeStyle) throws Exception {
        long startTime = System.currentTimeMillis();
        
        try {
            System.out.println("🚀 开始提取APK图标: " + apkFile.getName());
            System.out.println("📏 目标尺寸: " + targetSize + "x" + targetSize);
            System.out.println("⏱️ 超时设置: " + timeoutSeconds + "秒");
            
            // 1. 验证输入
            validateInput(apkFile, targetSize);
            
            // 2. 创建带超时的处理任务
            CompletableFuture<IconInfo> extractionFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return performIconExtraction(apkFile, targetSize, useNativeStyle);
                } catch (Exception e) {
                    throw new RuntimeException("图标提取失败: " + e.getMessage(), e);
                }
            });
            
            // 3. 等待完成或超时
            IconInfo result = extractionFuture.get(timeoutSeconds, TimeUnit.SECONDS);
            
            // 4. 更新统计
            updateStats(true, System.currentTimeMillis() - startTime);
            
            System.out.println("✅ 图标提取成功: " + apkFile.getName());
            return result;
            
        } catch (TimeoutException e) {
            updateStats(false, System.currentTimeMillis() - startTime);
            throw new Exception("图标提取超时 (" + timeoutSeconds + "秒): " + apkFile.getName(), e);
            
        } catch (ExecutionException e) {
            updateStats(false, System.currentTimeMillis() - startTime);
            Throwable cause = e.getCause();
            if (cause instanceof RuntimeException) {
                throw new Exception(cause.getMessage(), cause.getCause());
            } else {
                throw new Exception("图标提取执行失败: " + e.getMessage(), e);
            }
            
        } catch (Exception e) {
            updateStats(false, System.currentTimeMillis() - startTime);
            throw new Exception("图标提取失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 执行图标提取 - 带重试机制
     */
    private static IconInfo performIconExtraction(File apkFile, int targetSize) throws Exception {
        return performIconExtraction(apkFile, targetSize, true);
    }
    
    /**
     * 执行图标提取 - 带重试机制和风格选择
     */
    private static IconInfo performIconExtraction(File apkFile, int targetSize, boolean useNativeStyle) throws Exception {
        Exception lastException = null;
        
        for (int attempt = 1; attempt <= MAX_RETRY_ATTEMPTS; attempt++) {
            try {
                System.out.println("🔄 尝试第 " + attempt + " 次提取...");
                
                // 使用优化的处理器
                return performOptimizedExtraction(apkFile, targetSize, useNativeStyle);
                
            } catch (Exception e) {
                lastException = e;
                System.err.println("❌ 第 " + attempt + " 次尝试失败: " + e.getMessage());
                
                if (attempt < MAX_RETRY_ATTEMPTS) {
                    // 等待后重试
                    try {
                        Thread.sleep(1000 * attempt); // 递增等待时间
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new Exception("提取过程被中断", ie);
                    }
                }
            }
        }
        
        // 所有重试都失败了，使用fallback方法
        System.out.println("🔄 使用fallback方法...");
        return performFallbackExtraction(apkFile, targetSize, lastException);
    }
    
    /**
     * 执行优化的图标提取
     */
    private static IconInfo performOptimizedExtraction(File apkFile, int targetSize) throws Exception {
        return performOptimizedExtraction(apkFile, targetSize, true);
    }
    
    /**
     * 执行优化的图标提取 - 带风格选择
     */
    private static IconInfo performOptimizedExtraction(File apkFile, int targetSize, boolean useNativeStyle) throws Exception {
        try (ApkFile apk = new ApkFile(apkFile)) {
            // 1. 解析APK信息
            ApkParserLibrary.ApkInfo apkInfo = ApkParserLibrary.parseApkWithLibrary(apkFile);
            
            // 2. 解析图标资源
            ApkParserLibrary.IconResource iconResource = resolveIconResourceFallback(apk, apkInfo.getIconPath());
            
            if (iconResource == null) {
                throw new Exception("无法解析图标资源");
            }
            
            // 3. 根据图标类型选择处理器
            IconProcessor processor = selectProcessor(iconResource.getType(), useNativeStyle);
            
            // 4. 处理图标
            return processor.processIcon(apkInfo, iconResource, targetSize);
        }
    }
    
    /**
     * 执行fallback图标提取
     */
    private static IconInfo performFallbackExtraction(File apkFile, int targetSize, Exception originalException) throws Exception {
        try {
            System.out.println("🔄 使用fallback方法提取图标...");
            
            // 使用原始的StandardAdaptiveIconParser作为fallback
            try (ApkFile apk = new ApkFile(apkFile)) {
                // 查找Adaptive Icon XML文件
                String adaptiveIconPath = findAdaptiveIconPath(apk);
                
                if (adaptiveIconPath != null) {
                    // 使用标准解析器
                    StandardAdaptiveIconParser.AdaptiveIconResult result = 
                        StandardAdaptiveIconParser.parseAdaptiveIcon(apk, adaptiveIconPath);
                    
                    BufferedImage iconImage = StandardAdaptiveIconParser.renderAdaptiveIcon(result, targetSize);
                    
                    if (iconImage != null) {
                        return new IconInfo(iconImage, IconInfo.IconType.ADAPTIVE_ICON, adaptiveIconPath);
                    }
                }
                
                // 如果Adaptive Icon失败，尝试提取普通图标
                return extractStandardIcon(apk, targetSize);
            }
            
        } catch (Exception e) {
            // 如果fallback也失败，抛出原始异常
            throw new Exception("Fallback提取失败: " + e.getMessage() + 
                              " (原始错误: " + originalException.getMessage() + ")", e);
        }
    }
    
    /**
     * 查找Adaptive Icon路径
     */
    private static String findAdaptiveIconPath(ApkFile apk) {
        try {
            // 查找mipmap-anydpi-v26目录下的XML文件
            String[] candidates = {
                "res/mipmap-anydpi-v26/ic_launcher.xml",
                "res/mipmap-anydpi-v26/ic_launcher_round.xml",
                "res/mipmap-anydpi-v26/ic_launcher_adaptive_background.xml"
            };
            
            for (String candidate : candidates) {
                byte[] data = apk.getFileData(candidate);
                if (data != null) {
                    return candidate;
                }
            }
            
        } catch (Exception e) {
            System.err.println("查找Adaptive Icon路径失败: " + e.getMessage());
        }
        
        return null;
    }
    
    /**
     * 提取标准图标
     */
    private static IconInfo extractStandardIcon(ApkFile apk, int targetSize) throws Exception {
        try {
            // 查找标准PNG图标
            String[] candidates = {
                "res/mipmap-xxxhdpi/ic_launcher.png",
                "res/mipmap-xxhdpi/ic_launcher.png",
                "res/mipmap-xhdpi/ic_launcher.png",
                "res/mipmap-hdpi/ic_launcher.png",
                "res/mipmap-mdpi/ic_launcher.png"
            };
            
            for (String candidate : candidates) {
                byte[] data = apk.getFileData(candidate);
                if (data != null) {
                    BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
                    if (image != null) {
                        // 缩放到目标尺寸
                        BufferedImage scaledImage = scaleImage(image, targetSize);
                        return new IconInfo(scaledImage, IconInfo.IconType.PNG, candidate);
                    }
                }
            }
            
            throw new Exception("未找到可用的图标文件");
            
        } catch (Exception e) {
            throw new Exception("提取标准图标失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 解析图标资源 - fallback方法
     */
    private static ApkParserLibrary.IconResource resolveIconResourceFallback(ApkFile apk, String iconPath) {
        // 创建基本的IconResource
        return new ApkParserLibrary.IconResource(iconPath, "adaptive", 512, "xxxhdpi");
    }
    
    /**
     * 选择处理器 - 支持原生风格和优化风格
     */
    private static IconProcessor selectProcessor(String iconType) {
        if ("adaptive".equalsIgnoreCase(iconType)) {
            // 优先使用原生风格的处理器
            return new NativeStyleAdaptiveIconProcessor();
        } else {
            return new PngIconProcessor();
        }
    }
    
    /**
     * 选择处理器 - 指定风格
     */
    private static IconProcessor selectProcessor(String iconType, boolean useNativeStyle) {
        if ("adaptive".equalsIgnoreCase(iconType)) {
            if (useNativeStyle) {
                return new NativeStyleAdaptiveIconProcessor();
            } else {
                return new OptimizedAdaptiveIconProcessor();
            }
        } else {
            return new PngIconProcessor();
        }
    }
    
    /**
     * 验证输入参数
     */
    private static void validateInput(File apkFile, int targetSize) throws Exception {
        if (apkFile == null) {
            throw new IllegalArgumentException("APK文件不能为空");
        }
        
        if (!apkFile.exists()) {
            throw new IllegalArgumentException("APK文件不存在: " + apkFile.getPath());
        }
        
        if (!apkFile.getName().toLowerCase().endsWith(".apk")) {
            throw new IllegalArgumentException("文件不是APK格式: " + apkFile.getName());
        }
        
        if (targetSize <= 0 || targetSize > 2048) {
            throw new IllegalArgumentException("目标尺寸必须在1-2048之间: " + targetSize);
        }
        
        if (apkFile.length() == 0) {
            throw new IllegalArgumentException("APK文件为空: " + apkFile.getName());
        }
        
        if (apkFile.length() > 100 * 1024 * 1024) { // 100MB限制
            throw new IllegalArgumentException("APK文件过大 (>100MB): " + apkFile.getName());
        }
    }
    
    /**
     * 缩放图片
     */
    private static BufferedImage scaleImage(BufferedImage originalImage, int targetSize) {
        BufferedImage scaledImage = new BufferedImage(targetSize, targetSize, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = scaledImage.createGraphics();
        
        try {
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            g2d.drawImage(originalImage, 0, 0, targetSize, targetSize, null);
        } finally {
            g2d.dispose();
        }
        
        return scaledImage;
    }
    
    /**
     * 更新统计信息
     */
    private static synchronized void updateStats(boolean success, long processingTime) {
        totalProcessedCount++;
        totalProcessingTime += processingTime;
        
        if (success) {
            successCount++;
        } else {
            failureCount++;
        }
        
        // 定期清理缓存
        if (totalProcessedCount % 10 == 0) {
            cleanupCache();
        }
    }
    
    /**
     * 清理缓存
     */
    private static void cleanupCache() {
        try {
            OptimizedAdaptiveIconXmlParser.clearCache();
            OptimizedApkResourceResolver.clearCache();
            System.out.println("🧹 缓存清理完成");
        } catch (Exception e) {
            System.err.println("缓存清理失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取性能统计
     */
    public static String getPerformanceStats() {
        if (totalProcessedCount == 0) {
            return "暂无处理统计";
        }
        
        double avgProcessingTime = (double) totalProcessingTime / totalProcessedCount;
        double successRate = (double) successCount / totalProcessedCount * 100;
        
        return String.format(
            "处理统计: 总数=%d, 成功=%d, 失败=%d, 成功率=%.1f%%, 平均耗时=%.0fms",
            totalProcessedCount, successCount, failureCount, successRate, avgProcessingTime
        );
    }
    
    /**
     * 重置统计信息
     */
    public static void resetStats() {
        totalProcessingTime = 0;
        totalProcessedCount = 0;
        successCount = 0;
        failureCount = 0;
        System.out.println("📊 统计信息已重置");
    }
    
    /**
     * 关闭所有资源
     */
    public static void shutdown() {
        try {
            OptimizedAdaptiveIconProcessor.shutdown();
            OptimizedApkResourceResolver.shutdown();
            System.out.println("🔌 所有资源已关闭");
        } catch (Exception e) {
            System.err.println("关闭资源失败: " + e.getMessage());
        }
    }
}
